package com.amtf.datafile;

/**
 * @author hansong
 * 
 */
public class DataField {
	private String value = "";
	private DataColumnDefinition definition = null;

	// public DataField() {
	// this.definition = new DataColumnDefinition();
	// }

	public DataField(DataColumnDefinition definition) {
		this.definition = definition;
	}

	@Override
	protected DataField clone() {

		DataField newObj = new DataField(null);
		newObj.value = this.value;
		newObj.definition = this.definition.clone();

		return newObj;
	}

	public boolean isAllMatch() {
		return isLengthMatch() && isEmptyMatch() && isTypeMatch();
	}

	public boolean isLengthMatch() {
		if (definition.isCheckFormat()) {
			// if (this.length >= 0 && value.length() != this.length) {
			// return false;
			// }

			if (definition.getMaxLength() >= 0) {
				int len = value.length();
				if (len < definition.getMinLength() || len > definition.getMaxLength()) {
					return false;
				}
			}
		}

		return true;
	}

	public boolean isEmptyMatch() {
		if (definition.isCheckFormat()) {
			if (!definition.isAllowEmpty() && value.length() == 0) {
				return false;
			}
		}

		return true;
	}

	public boolean isTypeMatch() {
		if (definition.isCheckFormat()) {
			if (definition.isAllowEmpty() && value.length() == 0) {
				return true;
			}

			String tmpValue = null;
			switch (definition.getType()) {
			case ANY:
				break;
			case ALPHABET:
				tmpValue = value.trim().toLowerCase();
				for (int i = 0; i < tmpValue.length(); i++) {
					char c = tmpValue.charAt(i);
					if (!(c >= 'a' && c <= 'z')) {
						return false;
					}
				}
				break;
			case NUMERIC:
				tmpValue = value.trim();
				try {
					Double.parseDouble(tmpValue);
				} catch (Throwable e) {
					return false;
				}
				// for (int i = 0; i < tmpValue.length(); i++) {
				// char c = tmpValue.charAt(i);
				// if (!(c >= '0' && c <= '9')) {
				// return false;
				// }
				// }
				break;
			case ALPHABET_OR_NUMERIC:
				tmpValue = value.trim().toLowerCase();
				for (int i = 0; i < tmpValue.length(); i++) {
					char c = tmpValue.charAt(i);
					if (c != '.' && !(c >= 'a' && c <= 'z') && !(c >= '0' && c <= '9')) {
						return false;
					}
				}
				return true;
			default:
				return true;
			}
		}

		return true;
	}

	public String getName() {
		return this.definition.getName();
	}

	public String getValue() {
		return value;
	}

	public DataField setValue(String value) {
		if (value == null) {
			this.value = "";
		} else {
			if (definition.getQuote() != ' ' && value.length() != 0) {
				// value = value.trim();
				if (value.charAt(0) == definition.getQuote() && value.charAt(value.length() - 1) == definition.getQuote()) {
					value = value.substring(1, value.length() - 1);
				}
			}
			if (definition.isTrimValue()) {
				this.value = value.trim();
			} else {
				this.value = value;
			}
		}

		return this;
	}

	@Override
	public boolean equals(Object obj) {
		DataField f1 = (DataField) obj;
		return value.equals(f1.value) && definition.equals(f1.definition);
		// return value.equals(f1.value);
	}

	@Override
	public String toString() {
		String tmpValue = "";
		String padValue = definition.getPadValue();
		if (padValue.length() != 0) {
			String padString = "";
			int spaceCount = definition.getMaxLength() - value.length();
			switch (definition.getPadType()) {
			case LEFT_PAD:
				for (int i = 0; i < spaceCount; i++) {
					padString += padValue;
				}

				tmpValue = padString + value;
				break;
			case RIGHT_PAD:
				for (int i = 0; i < spaceCount; i++) {
					padString += padValue;
				}

				tmpValue = value + padString;
				break;
			default:
				tmpValue = value;
			}
		} else {
			tmpValue = value;
		}

		char quote = definition.getQuote();
		if (quote != ' ') {
			char demiliter = definition.getDataRecordDefinition().getColumnDelimiter();
			if (definition.isForceQuote()) {
				tmpValue = quote + tmpValue + quote;
			} else if (tmpValue.indexOf(demiliter) != -1) {
				tmpValue = quote + tmpValue + quote;
			}
		}

		return tmpValue;
	}

	public String getTrimValue() {
		return value.trim();
	}

	public DataColumnDefinition getDefinition() {
		return definition;
	}

	public void setDefinition(DataColumnDefinition definition) {
		this.definition = definition;
	}
}
